package edu.uts.reekie.designer.implementation.figures;

import org.eclipse.draw2d.AbstractConnectionAnchor;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.StackLayout;
import org.eclipse.draw2d.TextUtilities;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;

import edu.uts.reekie.designer.figures.MultipleFigure;

/*
 * TODO: implement multiple figure
 */
public class FileComponentFigure extends ViewComponentFigure implements MultipleFigure {
	
	private static final int MULTIPLICITY_OFFSET = 5;
	private static final Dimension FILE_IMAGE_SIZE = new Dimension(50,75);
	private static final Insets FILE_IMAGE_INSETS = new Insets(2,2,2,2);

	private Dimension textSize;
	private String name;
	
	Dimension getFileImageSize() {
		Dimension d = FILE_IMAGE_SIZE.getCopy();
		if (isMultiple) {
			d.height+=MULTIPLICITY_OFFSET;
		}
		return d;
	}
	
	public FileComponentFigure() {
		// set the font
		Font f = new Font(null,"Arial",11,SWT.NORMAL);
		setFont(f);
		
		setName("");
		
		setLayoutManager(new StackLayout());
		
		// set the fg/bg colours
		setBackgroundColor(ColorConstants.black);
		setForegroundColor(ColorConstants.black);
	}
	
	public Dimension getPreferredSize(int wHint, int hHint) {
		Dimension size = getFileImageSize();
		
		
		if (isMultiple){
			size.expand(MULTIPLICITY_OFFSET, MULTIPLICITY_OFFSET);
		}
		
		// expand the circle size horizontally by the text size
		if (textSize.height>size.height){
			size.expand(textSize.width, textSize.height - size.height);
		} else {
			size.expand(textSize.width,0);
		}
		return size;
	}
	
	Dimension getNameDimension() {
		TextUtilities tu = new TextUtilities();
		return tu.getTextExtents(name, getFont());
	}
	
	protected void paintFigure(Graphics g){
		
		Rectangle fileRect = getBounds().getCopy();
		Rectangle textRect = getBounds().getCopy();
		fileRect.setSize(FILE_IMAGE_SIZE);
		fileRect = fileRect.crop(FILE_IMAGE_INSETS);
		
		Rectangle multipleRect = fileRect.getCopy().expand(new Insets(-MULTIPLICITY_OFFSET,-MULTIPLICITY_OFFSET,MULTIPLICITY_OFFSET,MULTIPLICITY_OFFSET));
		
		// draw the multiple
		if (isMultiple)
			g.drawRectangle(multipleRect);
		
		//draw the file border
		g.setBackgroundColor(ColorConstants.white);
		g.setForegroundColor(ColorConstants.white);
		g.fillRectangle(fileRect);
		
		g.setForegroundColor(ColorConstants.black);
		g.drawRectangle(fileRect);
		
		
		g.setForegroundColor(ColorConstants.black);
		
		// draw the file lines
		int x1 = fileRect.x + 7;
		int x2 = fileRect.x + fileRect.width - 7;
		int y1 = fileRect.y + 5;
		int y2 = fileRect.y + 5;
		
		for (int i=0; i<10; i++){
			g.drawLine(x1,y1,x2,y2);
			y1+= 7;
			y2+=7;
		}
		
		// draw the main text if it's available
		if (name==null || name.equalsIgnoreCase("")){
		} else {
			int left = FILE_IMAGE_SIZE.width;
			if (isMultiple){
				left += MULTIPLICITY_OFFSET;
			}
			
			textRect.translate(left, 20);
			g.drawText(name,textRect.x,textRect.y);
		}
	}

	public String getName() {
		
		return name;
	}

	public void setName(String newName) {
		this.name = newName;	
		textSize = getNameDimension();
	}
	public ConnectionAnchor getAnchor() {
		return new FileComponentAnchor(this);
	}
	
	class FileComponentAnchor extends AbstractConnectionAnchor {
		
		
		public FileComponentAnchor(FileComponentFigure owner){
			super(owner);
		}
		
		private Rectangle getFileBounds() {
			Rectangle ownerBounds = getOwner().getBounds();
			
			Rectangle fileBounds = ownerBounds.getIntersection(
					new Rectangle(ownerBounds.x+FILE_IMAGE_INSETS.left,
								ownerBounds.y + FILE_IMAGE_INSETS.top,FILE_IMAGE_SIZE.width,
								FILE_IMAGE_SIZE.height));
			
			return fileBounds;
		}

		public Point getReferencePoint() {
			Point ref = getFileBounds().getCenter();
			getOwner().translateToAbsolute(ref);
			return ref;
			
		}
		
		/**
		 * Returns a point on the ellipse (defined by the owner's bounding box) where the
		 * connection should be anchored.
		 * @see org.eclipse.draw2d.ConnectionAnchor#getLocation(Point)
		 */
		public Point getLocation(Point reference) {
			Rectangle r = Rectangle.SINGLETON;
			r.setBounds(getFileBounds());
			r.translate(-1, -1);
			r.resize(1, 1);

			getOwner().translateToAbsolute(r);
			float centerX = r.x + 0.5f * r.width;
			float centerY = r.y + 0.5f * r.height;
			
			if (r.isEmpty() || (reference.x == (int)centerX && reference.y == (int)centerY))
				return new Point((int)centerX, (int)centerY);  //This avoids divide-by-zero

			float dx = reference.x - centerX;
			float dy = reference.y - centerY;
			
			//r.width, r.height, dx, and dy are guaranteed to be non-zero. 
			float scale = 0.5f / Math.max(Math.abs(dx) / r.width, Math.abs(dy) / r.height);

			dx *= scale;
			dy *= scale;
			centerX += dx;
			centerY += dy;

			return new Point(Math.round(centerX), Math.round(centerY));
		}
		
	}

	
	
}
